#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "String.h"
#include "Data.h"

void Print_String(char c)
{
	printf("%c", c);
}

static String* InitString(int maxlen)
{
	if (maxlen < 1) return NULL;
	String* s = malloc(sizeof(String));
	if (s)
	{
		s->base = (char*)malloc(sizeof(char) * (maxlen + 1));
		if (s->base)
		{
			s->curlen = 0;
			s->maxlen = maxlen;
			return s;
		}
		else
		{
			free(s);
			exit(-1);
			return NULL;
		}
	}
	else
	{
		exit(-1);
		return NULL;
	}
}

int GetStringLength(const String* s)
{
	return s->curlen;
}

int IsStringEmpty(const String* s)
{
	return !(s->curlen);
}

int IsStringFull(const String* s)
{
	return s->curlen == s->maxlen;
}

String* CreateString(const char* src)
{
	if (!src) return NULL;
	int str_len = strlen(src);
	String* s;
	if (!(s = InitString(str_len)))
		return NULL;
	for (int i = 0; i < str_len; i++)
	{
		s->base[i + 1] = src[i];
	}
	s->curlen = str_len;
	return s;
}

void TraverseString(String* s, void(*cb)(char))
{
	for (int i = 1; i <= s->curlen; i++)
	{
		cb(s->base[i]);
	}
}

int CompairString(const String* s1, const String* s2)
{
	int i1 = 1;
	int i2 = 1;
	while (i1 <= s1->curlen && i2 <= s2->curlen)
	{
		if (s1->base[i1] != s2->base[i2])
			return s1->base[i1] - s2->base[i2];
		else
		{
			i1++;
			i2++;
		}
	}
	if (i1 > s1->curlen && i2 > s2->curlen)
	{
		return 0;
	}
	else if (i1 > s1->curlen)
	{
		return s2->base[i2] * -1;
	}
	else
	{
		return s1->base[i1];
	}
}

Status CopyString(String* des, const String* src)
{
	if (des->curlen)
	{
		free(des->base);
	}
	if (src->curlen < 1) return ERROR;
	des->base = (char*)malloc(sizeof(char) * (src->curlen + 1));
	if (des->base)
	{
		des->maxlen = src->curlen;
		for (int i = 1; i <= src->curlen; i++)
		{
			des->base[i] = src->base[i];
		}
		des->curlen = src->curlen;
		return OK;
	}
	else
	{
		exit(-1);
		free(des);
		return ERROR;
	}
}

Status ConcatString(String* des, const String* src)
{
	char* tmp = (char*)realloc(des->base ,sizeof(char) * (des->curlen + src->curlen + 1));
	if (tmp)
	{
		des->base = tmp;
		des->maxlen = des->curlen + src->curlen;
		for (int i = des->curlen + 1, j = 1; i <= des->maxlen; i++, j++)
		{
			des->base[i] = src->base[j];
		}
		des->curlen = des->maxlen;
		return OK;
	}
	else
	{
		exit(-1);
		return ERROR;
	}
}

int IndexOf_BF(const String* s, const String* t, int pos)
{
	if (pos < 1 || pos > t->curlen)	return -1;
	int i = pos;
	int j = 1;
	while (i <= s->curlen && j <= t->curlen)
	{
		if (s->base[i] == t->base[j])
		{
			i++;
			j++;
		}
		else
		{
			i = i - j + 2;
			j = 1;
		}
	}
	if (j > t->curlen)
	{
		return i - t->curlen;
	}
	else
	{
		return -1;
	}
}